# 函数递归

"""
函数递归：
        嵌套调用中的特殊情况，即嵌套函数自己调用自己

    递归的代码，虽然很多时候看起来写法很简单，但是执行过程可能会非常复杂，在分析
递归代码的时候，光用脑子想，是很困难。
        1. 画图
        2. 调试器

    递归代码要有两个要素：
        1. 递归结束条件
        2. 递归的递推公式

    递归的缺点
    1. 执行过程非常复杂，难以理解
    2. 递归代码容易出现“栈溢出”(函数的调用栈)的情况---
        代码不小心写错了，导致每次递归，参数不能正确，
        参数不能正确的接近递归结束条件，出现无线递归的情况
    3. 递归代码一般都是可以转换成等价的循环代码的，并且，循环的版本通常运行
        速度要比递归的版本有优势(函数调用也是有开销的)

    递归的优点：
    1. 代码非常整洁，尤其是处理一些“问题本身就是通过递归的方式定义的”
"""

# 求n阶乘

# 用循环来求n的阶乘
# def factor(n):
#     result = 1
#     for i in range(1, n+1):
#         result *= i
#     return result
#
# m = factor(5)
# print(m)

# 用递归的方式来求n的阶乘
"""
    虽然都是n,但是n是函数形参，形参相当于函数的局部变量，局部变量在函数自己的
栈帧上的。虽然两个函数的局部变量名相同，但是是不同的栈帧，是不同的内存空间也就
是不同的变量了。另一方面，看起来是同一个函数，但是这里的两次调用，其实是两个栈帧
"""


def factor(n):
    if n == 1:
        return 1
    return n * factor(n-1)

print(factor(5))